perm filename CINEMA.SAI[GEM,HE] blob sn#107047 filedate 1974-06-15 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00016 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00003 00002	BEGIN "CINEMA" COMMENT KINETIC DISPLAY - BRUCE G. BAUMGART - MAY 1974
C00006 00003	FILE FORMATS
C00008 00004		REQUIRE "ABBREV[SYS,BGB]" SOURCE_FILE
C00010 00005	STRING PROCEDURE FILENAME(REFERENCE STRING STR1,STR2)
C00011 00006	SUBR DPYF(ITG I)				α DISPLAY I'TH FRAME
C00013 00007	PROCEDURE DPYIII(STRING STR)				α DISPLAY III FILE
C00015 00008	SUBR MERGE(STRING STR)		α INPUT A SEQUENCE OF FRAMES
C00017 00009	SUBR OSTRIP (STRING STR)		α OUTPUT A STRIP OF FRAMES
C00018 00010	SUBR ISTRIP (STRING STR)		α INPUT A STRIP OF FRAMES
C00020 00011	SUBR DPYFILM		α DISPLAY A FILM OF STRIPS
C00021 00012	SUBR SWDPY(ITG SWFLAG)			α SPACE WAR DISPLAY ROUTINE
C00024 00013	SUBR HELP		α RUN TIME COMMAND DOCUMENTATION
C00026 00014	SUBR INITIALIZATION
C00027 00015	SUBR LISTEN
C00030 00016	α MAIN EXECUTION
C00031 ENDMK
C⊗;
BEGIN "CINEMA" COMMENT KINETIC DISPLAY - BRUCE G. BAUMGART - MAY 1974;
COMMENT CINEMA DESIGN NOTES:

1. Data Rates.

	Moderately interesting frame requires about 1K words.
	24 Frames per second  *  60 seconds per minute
	=  1,440 frames   1 minute
	   2,880 frames   2 minutes
	   5,760 frames   4 minutes
	  11,520 frames   8 minutes
	  23,040 frames  16 minutes
	  46,080 frames  32 minutes
	  92,160 frames  64 minutes	  86,400 frames per hour

2. Memory capacities.

	CORE:		165K words.
	Disk System:	5 packs * 17 Megawords/pack  = 85 Megawords.
	UDP:		=7600 tracks * (=18 records of =128 word
			 		+ 1 record  of  =32 words)
			=7600 track * =2336 words per track = 17,753,600 words.
	Librascope:	32 bands of 76K of 1024 words = 2,432K = 2,490,368 words.
	Mag Tape:	K/foot * 2400 feet per reel  =  2.5 Megawords per tape.

3. Logical Structure.
	
	Film	   maximum 3 hours    1 to 10 Acts.
	Acts	   maximum 1 hour     1 to 10 Scenes.
	Scenes     1 to 20 minutes    1 to 10 takes.
	Takes	   1 minute	      1 to 100 strip
	Strips	   4 seconds	      1 to 100 frames
	Frames	   1/24 second

4. Desired Command functions:

	Display a single III plot file.
	Run a Strip of Film.
	Single Step a film.
	Merge frames of film into strip files.
	Unmerge a strip into a sequence of frames.
	Frame repetition.
------------------------------------------------------------------------------;
COMMENT FILE FORMATS
-------------------------------------------------------------------------------
III DISPLAY FILE (default extension PLT).
	3-WORD HEADER
		0 Ignored (a core byte pointer).
		1 File Size in words (exclusive of header).
		2 always contains zero.
	III VECTORS & TEXT.
		III Opcodes in low order bits of word:
			1 Text word 5 characters of 7 bit ASCII
		      146 Absolute Invisible Vector.
		      106 Absolute Visible Vector.
-------------------------------------------------------------------------------
FILM-STRIP FILE (default extension STP).
	128-WORD HEADER.
		28 WORDS: second word of header is total size (in words) of body.
		100 WORDS OF FRAME SIZES,
	BODY of file contains frames.
------------------------------------------------------------------------------;
	REQUIRE "ABBREV[SYS,BGB]" SOURCE_FILE;
	REQUIRE "DRUMER[SYS,BGB]" SOURCE_FILE;

	DEFINE UPGIOT ="'703000000000";
	DEFINE CALLI  ="'047000000000";
	DEFINE DISMIS ="'047000400024";
	DEFINE SPCWAR ="'043000000000";

α GLOBAL DECLARATION;
	ITG NFRAME;			α NUMBER OF CURRENTLY DISPLAYED FRAME;
	ITG ARRAY SIZE  [-28:100];	α FILM STRIP HEADER;
	ITG ARRAY FRAME [0:99];		α FRAME INDEX (OR CORE ADDRESSES);

	ITG NSTRIP;			α NUMBER OF CURRENTLY DISPLAYED STRIP;
	ITG ARRAY STNAME[0:99];		α SIXBIT STRIP NAMES;
	ITG ARRAY STRIP [0:99];		α STRIP INDEX (OF FAST BAND ADDRESSES);
	ITG ARRAY STRIPA[0:99];		α STRIP DISPLAY ARGUMENT (XWD DIRFLG,ITERATION);

	REAL FRAMES_PER_SEC;		α DEFAULT 24 FRAMES PER SECOND;
	ITG  FRAMES_PER_TICK;		α RIGHT HALFWORD, EIGHTEEN BIT FRACTION;
	INTEGER ARRAY INFO[0:6];	α FILE LOOKUP INFORMATION;

α THE INNER BLOCK IS FOR THE SAKE OF RUN TIME CORE ALLOCATION;

	XSUBR CORGET;		α SAIL'S CORE ALLOCATION;
	XSUBR CORREL;		α SAIL'S CORE DEALLOCATION;

BEGIN "INNER"	

	SAFE ITG ARRAY DPYBUF [0:1];	α DISPLAY BUFFER HEADER;
	ITG DPYBUF_SIZE;		α OF DPYBUF;

	SAFE ITG ARRAY FBDBUF [0:1];	α FAST BAND BUFFER HEADER;
	ITG FDBBUF_SIZE;		α OF DPYBUF;
STRING PROCEDURE FILENAME(REFERENCE STRING STR1,STR2);
BEGIN "FILENAME" α------------------------------------------------------------;
	ITG CHR;
α SPLIT ARGUMENT STRING INTO FILENAME PART & PPPN PART;
	BREAKSET(2,"[","I");				α SCAN FOR LEFT BRACKET;
	STR2 ← STR1;
	STR1 ← SCAN(STR2,2,CHR);
	STR2 ←  IF CHR=0 THEN "" ELSE
		IF "["≠STR2[∞ FOR 1] THEN "["&STR2&"]" ELSE "["&STR2;
	RETURN(STR1&STR2);
END "FILENAME"; α-------------------------------------------------------------;
SUBR DPYF(ITG I);				α DISPLAY I'TH FRAME;
BEGIN "DPYF" α----------------------------------------------------------------;
	ITG PTR,SIZ;
	IF I ≠ 0 MAX I MIN 99 THEN RETURN;
	PTR ← FRAME[I];	SIZ ← SIZE[I];
	IF (PTR LOR SIZ) THEN
	S⊂ UPGIOT PTR;JFCL;⊃;			α DISPLAY PIECE OF GLASS;
END "DPYF"; α BGB 28 MAY 1974 -------------------------------------------------;

BOOLEAN SUBR IFRAME (STRING STR;ITG I);			α INPUT A SINGLE FRAME;
BEGIN "IFRAME" α--------------------------------------------------------------;
	ITG TMP,FLG,PTR,SIZ;
	SIZE[I] ← FRAME[I] ← 0;

	OPEN(1,"DSK",8,3,0,0,0,0);
	LOOKUP(1,STR,FLG);
	IF FLG THEN ⊂ RELEASE(1);RETURN(FALSE);⊃;
	WORDIN(1);SIZ ← WORDIN(1);			α READ FIRST TWO WORDS;
	OUTSTR(9&"FRAME "&CVS(I)&(" "&9&"SIZE ")&CVS(SIZ));

	PTR ← DPYBUF_SIZE;
	ARRYIN(1,DPYBUF[PTR],SIZ);RELEASE(1);		α INPUT ONE FRAME TO DPYBUF;
	FRAME[I]←LOCATION(DPYBUF[PTR]);			α LOCATION OF FRAME;
	SIZE[I]←SIZ;					α SIZE OF FRAME;
	DPYBUF_SIZE ← PTR + SIZ;
	OUTSTR("	EOF"&↓);
	RETURN(TRUE);
END "IFRAME"; α BGB 28 MAY 1974 ----------------------------------------------;

PROCEDURE DPYIII(STRING STR);				α DISPLAY III FILE;
BEGIN "DPYIII" α--------------------------------------------------------------;
	ITG FLG,PTR,SIZ,CHR;
	STRING STR1,STR2;

	OPEN(1,"DSK",8,3,0,0,0,0);
	STR1←STR;STR ← FILENAME(STR1,STR2);
	LOOKUP(1,STR,FLG);
	IF FLG THEN LOOKUP(1,STR1&".PLT"&STR2,FLG);
	IF FLG THEN ⊂ OUTSTR(" FILE →→"&STR&"←← NOT FOUND."&↓);RELEASE(1);⊃;

α III DISPLAY BUFFER INPUT;
	WORDIN(1);SIZ ← WORDIN(1);			α READ FIRST TWO WORDS;
BEGIN
	ITG ARRAY DPYBUF[0:SIZ];			α ALLOCATE SPACE;
	ARRYIN(1,DPYBUF[0],SIZ);RELEASE(1);		α INPUT ONE FRAME TO DPYBUF;
	PTR←LOCATION(DPYBUF[0]);			α LOCATION OF FRAME;
	S⊂ UPGIOT PTR;JFCL;⊃;
END;
END "DPYIII"; α BGB 28 MAY 1974 ----------------------------------------------;
SUBR MERGE(STRING STR);		α INPUT A SEQUENCE OF FRAMES;
BEGIN "MERGE" α---------------------------------------------------------------;
	STRING STR1,STR2;
	ITG CHR,FLG,FILSIZ,TOTAL,I;

α SPLIT ARGUMENT STRING INTO FILENAME PART & PPPN PART;
	STR2 ← STR;STR1 ← SCAN(STR2,2,CHR);
	IF CHR=0 THEN STR2←"" ELSE STR2 ←"["&STR2;
	TOTAL←0;

α SCAN THE UFD FOR PLOT FILE FRAMES;
	CALL(0,"GETPPN");

α DO LOOKUPS AND ACCUMULATE CORESIZE;
	OPEN(1,"DSK",8,3,0,0,0,0);
	FOR I←0 THRU 99 DO
	BEGIN "LOOKUP"
		LOOKUP(1,STR1&"."&CVS(I)&STR2,FLG);
		IF FLG∧(I≠0) THEN DONE;
		FILEINFO(INFO);
		FILSIZ ← ABS(INFO[3]ASH -18);
		TOTAL ← FILSIZ + TOTAL;
	END "LOOKUP";
	RELEASE(1);
	OUTSTR("TOTAT FILM SIZE = "&CVS(TOTAL)&↓);

α ALLOCATE DPYBUF TO HOLD THIS STRIP OF FRAMES;
S⊂ 	MOVE 2,DPYBUF;
	SKIPE DPYBUF_SIZE;PUSHJ '17,CORREL;	α GIVE BACK OLD SPACE;
	MOVE 3,TOTAL;PUSHJ '17,CORGET;JFCL;	α GET NEW SPACE;
	MOVEM 2,DPYBUF;⊃;

	DPYBUF_SIZE ← 0;
	IFRAME(STR1&".0"&STR2,0);	α ZERO'TH FRAME (OPTIONAL EXISTENCE);
	FOR I←1 THRU 99 DO 
	IF IFRAME(STR1&"."&CVS(I)&STR2,I) THEN ELSE DONE;
END "MERGE"; α BGB 1 JUNE 1974 -----------------------------------------------;
SUBR OSTRIP (STRING STR);		α OUTPUT A STRIP OF FRAMES;
BEGIN "OSTRIP" α--------------------------------------------------------------;
	ITG FLG;
	IF DPYBUF_SIZE = 0 THEN RETURN;

	OPEN(1,"DSK",8,0,3,0,0,0);
	ENTER(1,STR&".STP",FLG);

	SIZE[-27] ← DPYBUF_SIZE;			α SIZE OF SNIP IN WORDS;
	ARRYOUT(1,SIZE[-28],128);
	ARRYOUT(1,DPYBUF[0],DPYBUF_SIZE);
	RELEASE(1);OUTSTR("	EOF."&↓);
END "OSTRIP"; α --------------------------------------------------------------;

SUBR ISTRIP (STRING STR);		α INPUT A STRIP OF FRAMES;
BEGIN "ISTRIP" α -------------------------------------------------------------;
	ITG I,FLG,PTR;
	STRING STR1,STR2;

α OPEN THE FILE AND READ THE HEADER;
	OPEN(1,"DSK",15,3,0,0,0,0);
	STR1←STR;STR←FILENAME(STR1,STR2);
	LOOKUP(1,STR,FLG);
	IF FLG THEN LOOKUP(1,STR1&".STP"&STR2,FLG);
	IF FLG THEN ⊂ RELEASE(1);RETURN;⊃;

	ARRYIN(1,SIZE[-28],128);PTR←SIZE[-27];
	IF PTR<20 ∨ PTR>128000 THEN 
	⊂ OUTSTR(9&"→→ "&STR&" ←← DOESN'T SEEM TO BE A FILM."&↓);RETURN;⊃;

α ADJUST DPYBUF SIZE;
	S⊂ MOVE 2,DPYBUF;
	SKIPE DPYBUF_SIZE;PUSHJ '17,CORREL;	α GIVE BACK OLD SPACE;
	SETZ 2,;MOVE 3,PTR;MOVEM 3,DPYBUF_SIZE;	α ALLOCATE NEW MEMORY SPACE;
	PUSHJ '17,CORGET;JFCL;			α GET NEW SPACE;
	MOVEM 2,DPYBUF;⊃;

α READ THE FILE INTO DPYBUF;
	ARRYIN(1,DPYBUF[0],PTR);
	RELEASE(1);OUTSTR("	EOF."&↓);

α SETUP INDEX OF FRAME POINTERS;
	PTR ← 0;FOR I← 0 THRU 99 DO IF SIZE[I]≠0 THEN ⊂
	FRAME[I]←LOCATION(DPYBUF[PTR]);PTR←PTR+SIZE[I];⊃ ELSE
	FRAME[I]←0;

END "ISTRIP"; α --------------------------------------------------------------;
SUBR DPYFILM;		α DISPLAY A FILM OF STRIPS;
BEGIN "DPYFILM"
	ITG BUFPTR,FBPTR;
	ITG I,SIZE;

α FIND MAXIMUM STRIP FILE SIZE;
	SIZE ← 0;
	FOR I←0 THRU 99 DO SIZE←SIZE MAX (STRIP[I] LAND '777777);

α ALLOCATE DPYBUF AND FBDBUF TO ACCOMDATE MAXIMUM SIZE STRIP;

α GET FIRST STRIP;
	BUFPTR ← LOCATION(FBDBUF[0]);

α START SPACE WAR DISPLAY OF FIRST STRIP (AND RETURN EXECUTION TO HERE);

α GET NEXT SEQUENTIAL STRIP OF IMAGES;
	DRUMI(BUFPTR,FBPTR);

α WAIT FOR SPACE WAR TO FINISH DISPLAYING PREVIOUS STRIP;

END "DPYFILM";
SUBR SWDPY(ITG SWFLAG);			α SPACE WAR DISPLAY ROUTINE;
S⊂ "SWDPY" α -----------------------------------------------------------------;
	ITG FTIME,PTR,SIZ,I;
	LABEL L0,L1,SA,L2,L3,L4,EOL;

α FIRE UP SPACE WAR JOB;
L0:	SETOM I;SETZM FTIME;
	HRLI '400002;			α RUN ON PDP-10 EVERY 1/30 OF A SECOND;
	HRRI SA;			α START ADDRESS OF SPACE WAR MODULE;
	CALLI '400003;			α SWCGO;
	SETZ;CALLI '400021;MOVEM '10;	α SEGNUM TO AC10;
	CALLI '400017;			α DETSEG;

α WAIT FOR FURTHER COMMANDS;
L1:	'51000000001;			α INCHRW WAIT FOR SPACE;
	MOVE 2,1;ANDI 1,'177;		α STRIP OF META-CTRL BITS;
	CAIE 1,'40;JRST L1;
	SPCWAR '636367;			α STOP THE SPACE WAR MODULE;
	MOVSI 1,'64240;'51000000001 3,;	α OUTSTR(CRLF);
	CALLI '10,'400016;JRST 4,;	α ATTSEG FROM AC10;
	JRST EOL;

α SPACE WAR MODULE;
SA:	MOVE FTIME;ADD FRAMES_PER_TICK;HRRZM FTIME;	α  UPDATE TIME;
	TLNN -1;DISMIS;
L4:	AOS 1,I;CAILE 1,99;SETZM I;	α TEST FOR END OF LOOP;
	MOVE 1,I; ADD 1,FRAME;		α PTR ← FRAME[I];
	SKIPN 1,(1);JRST L4;MOVEM 1,PTR;
	MOVE 1,I;ADD 1,SIZE;ADDI 1,28;	α SIZ ← SIZE[I];
	MOVE(1);MOVEM SIZ;
	JRST 3,@L2;L2: L3;		α LEAVE USER IOT MODE;
L3: 	UPGIOT PTR;JFCL;DISMIS;		α DISPLAY PIECE OF GLASS;

α END OF LOOP;
EOL:    MOVE I;MOVEM NFRAME;		α SAVE CURRENT FRAME NUMBER;
END "SWDPY"; α ---------------------------------------------------------------;
SUBR HELP;		α RUN TIME COMMAND DOCUMENTATION;
α-----------------------------------------------------------------------------;
OUTSTR("
	MERGE <NAME>	;READS IN A SEQUENCE OF PLOT FILES NAME.0 TO NAME.99
	IN  <FILM>	;READS IN A FILM FILE.
	OUT <FILM>	;OUTPUTS A FILM FILE.
	RUN 		;RUN A FILM CONTINUOUSLY USING SPACE WAR MODE.
	FRAME <N>	;DISPLAYS THE N'TH FRAME.
	DPY <NAME>	;INPUT AND DISPLAY A SINGLE PLOT FILE.
	EXIT		;RETURNS CONTROL TO MONITOR LEVEL.
	SPEED <REAL>	;SET SPEED - FRAMES PER SECOND - FASTEST 30.0/SEC
	<SPACE>		;SINGLE STEP THE FILM.
");
α-----------------------------------------------------------------------------;

SUBR SPEED (STRING STR);
BEGIN "SPEED"
	REAL I; ITG CHR;
	I ← FRAMES_PER_SEC;
	IF LENGTH(STR)=0 THEN
	⊂ OUTSTR("THE SPEED IS "&CVG(I)&" FRAME"&(IF I=1 THEN "" ELSE "S")&
	  " PER SECOND."&↓);RETURN;⊃;
	I ← (ABS(REALSCAN(STR,CHR)) MIN 30) MAX 0.1;
	FRAMES_PER_SEC ← I;
	FRAMES_PER_TICK ← (I * 2↑18)/30;
END "SPEED";
SUBR INITIALIZATION;
BEGIN "INITIAL"

	FRAMES_PER_SEC  ←  24;
	FRAMES_PER_TICK ← (24 ASH 18)%30;
	BREAKSET(1," ","I");
	BREAKSET(2,"[","I");
	OUTSTR("Type HELP<RETURN> for commands."& ↓);

END "INITIAL";
SUBR LISTEN;
BEGIN "LISTEN"
	STRING CMLINE,CMD;ITG CHR;
	OUTSTR("*");

α SINGLE CHARACTER ACTIVATION COMMANDS;
	DO BEGIN "PREVIEW"
		S⊂ CALLI '400063;MOVEM CHR ⊃;
		IF CHR="#" THEN ⊂ INCHRW;OUTSTR(13&12&12&12&12&12);⊃ ELSE
		IF CHR=" " ∨ CHR=10 THEN ⊂ INCHRW;OUTCHR(13);
		NFRAME ← NFRAME+1;IF NFRAME=99 ∨ SIZE[NFRAME]=0 THEN NFRAME←1;
		DPYF(NFRAME);⊃ ELSE CHR←0;
	END "PREVIEW" UNTIL CHR=0;

α INPUT ACTUAL COMMAND LINE;
	CMLINE ← INCHWL;
	IF LENGTH(CMLINE)=0 THEN RETURN;
	CMD ← SCAN(CMLINE,1,CHR);

α DISPATCH COMMAND EXECUTION;

	IF EQU(CMD,"HELP")	THEN HELP ELSE
	IF EQU(CMD,"MERGE")	THEN MERGE (CMLINE) ELSE
	IF EQU(CMD,"IN")	THEN ISTRIP(CMLINE) ELSE
	IF EQU(CMD,"OUT")	THEN OSTRIP(CMLINE) ELSE
	IF EQU(CMD,"RUN")	THEN 
BEGIN
	ITG FLG,CHR,CNT;
	IF LENGTH(CMLINE)≠0 THEN ⊂
		CHR ← CMLINE;CNT ← INTSCAN(CMLINE,FLG);
		FLG ← (IF CHR="+" THEN 1 ELSE IF CHR="-" THEN -1 ELSE 0);
		FLG ← (FLG LSH 18)LOR ((ABS CNT)LAND '377777);
⊃;	OUTSTR(12&12&12&12&12);
	SWDPY(FLG);
END ELSE
	IF EQU(CMD,"FRAME")	THEN DPYF(INTSCAN(CMLINE,CHR)) ELSE
	IF EQU(CMD,"DPY")	THEN DPYIII(CMLINE) ELSE
	IF EQU(CMD,"EXIT")	THEN Q⊂ CALLI '12 ⊃ ELSE
	IF EQU(CMD,"SPEED")	THEN SPEED(CMLINE) ELSE

	OUTSTR(9&"→→ "&CMD&" ←← NO SUCH COMMAND. TYPE HELP FOR COMMAND LIST."&↓);

END "LISTEN";
α MAIN EXECUTION;
	INITIALIZATION;
	WHILE TRUE DO LISTEN;

END "INNER"
END "CINEMA";